package org.example.generics;

import java.lang.reflect.InvocationTargetException;

public class Demo {
    public static class Pair<T> {
        public T first;
        public T second;

        // 构造函数传参
        // 在泛型类的构造函数中传入泛型类型的Class对象，再通过反射来实例化泛型类型的对象
        public Pair(Class<T> type) {
            try {
                char[] s = {'1', '3', '4'};
                first = type.getDeclaredConstructor(char[].class).newInstance(s);
                second = type.getDeclaredConstructor(char[].class).newInstance(s);
            } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException |
                     InstantiationException e) {
                throw new RuntimeException(e);
            }
        }

        public interface Factory<T> {
            T createInstance();
        }

        public static class StringFactory implements Factory<String> {

            @Override
            public String createInstance() {
                return "123";
            }
        }

        // 通过工厂方法实例化
        // 定义接口或抽象类，使用具体的实现类来创建泛型类型的对象
        public Pair(Factory<T> factory) {
            first = factory.createInstance();
            second = factory.createInstance();
        }

        // 使用具体的子类
        // 如果我们已经知道了泛型类型的具体子类，那么我们也可以直接使用子类来实例化泛型类型
        public Pair() {
            first = (T) "321";
            second = (T) "";
        }

    }

    public static void main(String[] args) {
        Pair<String> pair1 = new Pair<>(String.class);
        Pair<String> pair2 = new Pair<>(new Pair.StringFactory());
        Pair<String> pair3 = new Pair<>();
        System.out.println(pair1.first);   // 134
        System.out.println(pair2.first);   // 123
        System.out.println(pair3.first);   // 321
    }
}
